﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Aliphant.ChatAI.Utility
{
    public static class JsonHelper
    {
        #region Read

        public static bool ReadJson<T>(string fileName, out T? obj, JsonConverter? converter = null) where T : class
        {
            bool res = ReadJsonFile(fileName, out string content);
            if (res)
            {
                try
                {
                    obj = converter == null ? JsonConvert.DeserializeObject<T>(content) :
                        JsonConvert.DeserializeObject<T>(content, converter);
                    return true;
                }
                catch
                {

                }
            }
            obj = default;
            return false;
        }

        public static JArray? ReadJsonArray(string fileName)
        {
            bool res = ReadJsonFile(fileName, out string json);
            if (res)
            {
                return JArray.Parse(json);
            }
            return null;
        }

        public static dynamic? ReadJson(string fileName)
        {
            bool res = ReadJsonFile(fileName, out string json);
            if (res)
            {
                return JObject.Parse(json);
            }
            return null;
        }

        public static bool ReadJsonFile(string fileName, out string json)
        {
            if (File.Exists(fileName))
            {
                using var reader = new StreamReader(fileName);
                try
                {
                    string buff = reader.ReadToEnd();
                    reader.Close();

                    json = buff;
                    return true;
                }
                catch
                {

                }
            }
            json = string.Empty;
            return false;
        }

        #endregion

        #region Save

        public static bool SaveToJson<T>(ref T obj, string fileName)
        {
            string json = JsonConvert.SerializeObject(obj, Formatting.Indented);
            return SaveFile(fileName, json);
        }

        public static bool SaveJArray(JArray array, string fileName)
        {
            string json = array.ToString(Formatting.Indented);
            return SaveFile(fileName, json);
        }

        public static bool SaveFile(string fileName, string content)
        {
            using var writer = new StreamWriter(fileName);
            try
            {
                writer.Write(content);
                writer.Close();
                return true;
            }
            catch
            {
                return false;
            }
        }

        public static bool LogFile(string fileName, string content)
        {
            using FileStream fs = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.Read);
            using StreamWriter writer = new StreamWriter(fs);
            try
            {
                writer.WriteLine(content);
                return true;
            }
            catch
            {
                return false;
            }
        }

        #endregion

    }
}
